package com.qianli.cashmama.trade.domain.services.impl;

import com.fqgj.common.utils.CollectionUtils;
import com.qianli.cashmama.trade.client.vo.UserLevelVO;
import com.qianli.cashmama.trade.common.utils.CalculatorUtils;
import com.qianli.cashmama.trade.dao.TBillDao;
import com.qianli.cashmama.trade.dao.TUserLevelConfigRulesDao;
import com.qianli.cashmama.trade.dao.TUserLevelDetailDao;
import com.qianli.cashmama.trade.entity.TBillEntity;
import com.qianli.cashmama.trade.entity.TUserLevelConfigRulesEntity;
import com.qianli.cashmama.trade.entity.TUserLevelDetailEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
 * Created with IntelliJ IDEA.
 * User: sm
 * Date: 2019-12-19
 * Time: 14:01
 */
@Service
public class UserLevelService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserLevelService.class);

    @Autowired
    private TUserLevelConfigRulesDao userLevelConfigRulesDao;

    @Autowired
    private TUserLevelDetailDao userLevelDetailDao;


    @Autowired
    private TBillDao billDao;

    public UserLevelVO getLevel(String userCode, String categoryCode, Integer level, String extraInfo) {

        if (level == null) {
            TUserLevelDetailEntity userLatestRecored = userLevelDetailDao.getUserLatestRecored(userCode, categoryCode);
            if (userLatestRecored != null) {
                level = userLatestRecored.getLevel();
            }
        }

        UserLevelVO userLevel = getUserLevel(userCode, categoryCode, level, extraInfo);
        storeLevelHistory(userCode, categoryCode, userLevel.getLevel());
        return userLevel;
    }

    private UserLevelVO getUserLevel(String userCode, String categoryCode, Integer level, String extraInfo) {
        LOGGER.info("getUserLevel请求,userCode:{},categoryCode:{},level:{},extraInfo:{}", userCode, categoryCode, level, extraInfo);
        UserLevelVO userLevelVO = new UserLevelVO()
                .setUserCode(userCode)
                .setCategoryCode(categoryCode)
                .setLevel(level);

        Integer paidTimes = 0;
        BigDecimal lastBorrowCapital = BigDecimal.ZERO;
        Integer latestTimesMaxOverdueDays = 0;
        Integer latestTimesMinOverdueDays = 0;
        Integer lastOverdueDays = 0;

        List<TBillEntity> tBillEntities = billDao.selectLatestListByUserCodeAndCategoryCode(categoryCode, userCode, 100);
        if (CollectionUtils.isEmpty(tBillEntities)) {
            LOGGER.info("当前用户的历史借款记录为空,userCode:{},categoryCode:{},level:{},extraInfo:{}", userCode, categoryCode, level, extraInfo);
        } else {
            paidTimes = tBillEntities.size();

            Collections.sort(tBillEntities, (TBillEntity b1, TBillEntity b2) -> b2.getId().compareTo(b1.getId()));
            TBillEntity lastBill = tBillEntities.get(0);
            lastBorrowCapital = lastBill.getBorrowCapital();
            lastOverdueDays = CalculatorUtils.overDueDays(lastBill.getRepaymentDate(), lastBill.getPayOffDate());
        }

        TUserLevelConfigRulesEntity tUserLevelConfigRulesEntity = userLevelConfigRulesDao.selectActiveOneByCategoryCodeAndLastBorrowCapital(categoryCode, lastBorrowCapital);
        if (tUserLevelConfigRulesEntity == null) {
            LOGGER.info("没有找到当前用户需要的用户提额的配置,userCode:{},categoryCode:{},level:{},extraInfo:{}", userCode, categoryCode, level, extraInfo);
            return userLevelVO;
        }

        LOGGER.info("找到当前用户需要的用户提额的配置,userCode:{},categoryCode:{},level:{},extraInfo:{},tUserLevelConfigRulesEntity:{}", userCode, categoryCode, level, extraInfo, tUserLevelConfigRulesEntity);
        Integer latestTimesToConsider = tUserLevelConfigRulesEntity.getLatestTimesToConsider();
        latestTimesToConsider = paidTimes >= latestTimesToConsider ? latestTimesToConsider : paidTimes;

        List<TBillEntity> targetBillList = new ArrayList<>();
        for (int i = 0; i < latestTimesToConsider; i++) {
            targetBillList.add(tBillEntities.get(i));
        }

        for (TBillEntity bill : targetBillList) {
            int overDueDays = CalculatorUtils.overDueDays(bill.getRepaymentDate(), bill.getPayOffDate());
            if (overDueDays >= latestTimesMaxOverdueDays) {
                latestTimesMaxOverdueDays = overDueDays;
            } else {
                latestTimesMinOverdueDays = overDueDays;
            }
        }

        //如果还款的次数低于配置的次数那么返回之前的用户等级
        if (tUserLevelConfigRulesEntity.getNeedMinPaidTimes() > paidTimes) {
            LOGGER.info("还款次数不够,userCode:{},categoryCode:{},level:{},extraInfo:{},tUserLevelConfigRulesEntity:{}", userCode, categoryCode, level, extraInfo, tUserLevelConfigRulesEntity);
            return userLevelVO;
        }
        //如果上比还款的逾期天数大于配置的最大逾期天数那么返回之前的等级
        if (tUserLevelConfigRulesEntity.getLastOverdueDays() < lastOverdueDays) {
            LOGGER.info("上比逾期天数不满足,userCode:{},categoryCode:{},level:{},extraInfo:{},tUserLevelConfigRulesEntity:{}", userCode, categoryCode, level, extraInfo, tUserLevelConfigRulesEntity);
            return userLevelVO;
        }
        //如果最近还款的逾期小于配置的最小逾期天数那么返回之前等级 防止恶意刷等级
        if (tUserLevelConfigRulesEntity.getLatestTimesMinOverdueDays() > latestTimesMinOverdueDays) {
            LOGGER.info("最小逾期天数不满足,userCode:{},categoryCode:{},level:{},extraInfo:{},tUserLevelConfigRulesEntity:{}", userCode, categoryCode, level, extraInfo, tUserLevelConfigRulesEntity);
            return userLevelVO;
        }
        //如果最近的逾期天数大于配置的值配置允许的最大逾期天数那么返回之前的等级
        if (tUserLevelConfigRulesEntity.getLatestTimesMaxOverdueDays() < latestTimesMaxOverdueDays) {
            LOGGER.info("最大逾期天数不满足,userCode:{},categoryCode:{},level:{},extraInfo:{},tUserLevelConfigRulesEntity:{}", userCode, categoryCode, level, extraInfo, tUserLevelConfigRulesEntity);
            return userLevelVO;
        }

        //返回新的用户等级
        userLevelVO.setBorrowCapital(tUserLevelConfigRulesEntity.getNowBorrowCapital().toString())
                .setLevel(tUserLevelConfigRulesEntity.getLevel());

        return userLevelVO;
    }

    private void storeLevelHistory(String userCode, String categoryCode, Integer level) {
        TUserLevelDetailEntity userLevelDetailEntity = new TUserLevelDetailEntity()
                .setLevel(level)
                .setUserCode(userCode)
                .setCategoryCode(categoryCode);

        userLevelDetailDao.insert(userLevelDetailEntity);
    }
}
